package com.fulihui.wgj.dal.mybatis.repository;

import com.fulihui.wgj.dal.mybatis.domain.WxSevenRetention;
import com.fulihui.wgj.dal.mybatis.domain.WxSubscribeStatistics;
import com.fulihui.wgj.dal.mybatis.mapper.WxSevenRetentionMapper;
import com.fulihui.wgj.dal.mybatis.mapper.WxSubscribeStatisticsMapper;
import com.fulihui.wgj.facade.dto.WxSevenRetentionDTO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.text.NumberFormat;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author wang_wx
 * @date 2018-07-03
 */
@Component
public class WxSevenRetentionRepository extends BaseRepository<WxSevenRetention> {

    private static final Logger LOGGER = LoggerFactory.getLogger(WxSevenRetentionRepository.class);

    @Resource
    WxSevenRetentionMapper wxSevenRetentionMapper;

    @Resource
    WxSubscribeStatisticsMapper wxSubscribeStatisticsMapper;

    /**
     * 字符串0
     */
    private final String ZERO_STR = "0";
    private final String ZERO_PERCENT = "0%";

    /**
     * 查询是否存在 -- 根据appId 和 date
     *
     * @param wxSevenRetention
     * @return
     */
    public int countByAppIdAndDate(WxSevenRetention wxSevenRetention) {
        Example example = bulidExample(wxSevenRetention);
        return wxSevenRetentionMapper.selectCountByExample(example);
    }

    /**
     * 查询列表-DTO包含粉丝
     *
     * @param appId     公众号appId
     * @param beginDate 开始时间
     * @param endDate   结束时间
     * @return
     */
    public List<WxSevenRetentionDTO> queryListDTO(String appId, String beginDate, String endDate) {
        List<WxSevenRetentionDTO> dtos = Lists.newArrayList();
        Example example = new Example(WxSevenRetention.class);
        Example.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(appId)) {
            criteria.andEqualTo("appId", appId);
        }
        if (StringUtils.isNotBlank(beginDate)) {
            criteria.andGreaterThanOrEqualTo("date", beginDate);
        }
        if (StringUtils.isNotBlank(endDate)) {
            criteria.andLessThanOrEqualTo("date", endDate);
        }
        example.orderBy("date").asc();

        List<WxSevenRetention> wxSevenRetentions = wxSevenRetentionMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(wxSevenRetentions)) {
            wxSevenRetentions.forEach(wxSevenRetention -> {
                WxSevenRetentionDTO wxSevenRetentionDTO = new WxSevenRetentionDTO();
                String date = wxSevenRetention.getDate();
                Example example1 = new Example(WxSubscribeStatistics.class);
                Example.Criteria criteria1 = example1.createCriteria();
                criteria1.andEqualTo("appId", appId);
                criteria1.andEqualTo("refDate", date);
                WxSubscribeStatistics subscribeStatistics = wxSubscribeStatisticsMapper.selectOneByExample(example1);
                wxSevenRetentionDTO.setDate(date);
                wxSevenRetentionDTO.setAppId(wxSevenRetention.getAppId());
                // 计算留存率
                if (Objects.nonNull(subscribeStatistics)) {
                    String newUserStr = subscribeStatistics.getNewUser();
                    wxSevenRetentionDTO.setNewUser(StringUtils.isNotBlank(newUserStr) ? newUserStr : ZERO_STR);
                    Integer newUser = 0;
                    if (StringUtils.isNotBlank(newUserStr)) {
                        newUser = Integer.valueOf(newUserStr);
                    }
                    wxSevenRetentionDTO.setZeroDay(getPercent(newUser, wxSevenRetention.getZeroDay(), 1));
                    wxSevenRetentionDTO.setOneDay(getPercent(newUser, wxSevenRetention.getOneDay(), 1));
                    wxSevenRetentionDTO.setTwoDay(getPercent(newUser, wxSevenRetention.getTwoDay(), 1));
                    wxSevenRetentionDTO.setThreeDay(getPercent(newUser, wxSevenRetention.getThreeDay(), 1));
                    wxSevenRetentionDTO.setFourDay(getPercent(newUser, wxSevenRetention.getFourDay(), 1));
                    wxSevenRetentionDTO.setFiveDay(getPercent(newUser, wxSevenRetention.getFiveDay(), 1));
                    wxSevenRetentionDTO.setSixDay(getPercent(newUser, wxSevenRetention.getSixDay(), 1));
                    wxSevenRetentionDTO.setSevenDay(getPercent(newUser, wxSevenRetention.getSevenDay(), 1));
                }
                dtos.add(wxSevenRetentionDTO);
            });
        }
        return dtos;
    }

    /**
     * 获取留存率
     *
     * @param subSum   关注数
     * @param unSubSum 取关数
     * @param digit    保留小数
     * @return
     */
    private String getPercent(Integer subSum, Integer unSubSum, Integer digit) {
        String percent = null;
        if (Objects.nonNull(subSum) && Objects.nonNull(unSubSum) && 0 != subSum) {
            double d = Double.valueOf(subSum - unSubSum) / subSum;
            NumberFormat nf = NumberFormat.getPercentInstance();
            nf.setMinimumFractionDigits(digit);
            percent = nf.format(d);
        } else if (Objects.nonNull(subSum) && Objects.nonNull(unSubSum) && 0 == subSum) {
            percent = ZERO_PERCENT;
        }
        return percent;
    }

    /**
     * 查询列表
     *
     * @param appId     公众号appId
     * @param beginDate 开始时间
     * @param endDate   结束时间
     * @return
     */
    public List<WxSevenRetention> queryList(String appId, String beginDate, String endDate) {
        Example example = new Example(WxSevenRetention.class);
        Example.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(appId)) {
            criteria.andEqualTo("appId", appId);
        }
        if (StringUtils.isNotBlank(beginDate)) {
            criteria.andGreaterThanOrEqualTo("date", beginDate);
        }
        if (StringUtils.isNotBlank(endDate)) {
            criteria.andLessThanOrEqualTo("date", endDate);
        }
        example.orderBy("date").asc();
        return wxSevenRetentionMapper.selectByExample(example);
    }

    /**
     * 查询列表-分页-DTO包含粉丝数
     *
     * @param appId     公众号appId
     * @param beginDate 开始时间
     * @param endDate   结束时间
     * @param page
     * @param rows
     * @return
     */
    public PageInfo<WxSevenRetentionDTO> queryPageListDTO(String appId, String beginDate, String endDate, Integer page, Integer rows) {
        List<WxSevenRetentionDTO> dtos = Lists.newArrayList();
        Example example = new Example(WxSevenRetention.class);
        Example.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(appId)) {
            criteria.andEqualTo("appId", appId);
        }
        if (StringUtils.isNotBlank(beginDate)) {
            criteria.andGreaterThanOrEqualTo("date", beginDate);
        }
        if (StringUtils.isNotBlank(endDate)) {
            criteria.andLessThanOrEqualTo("date", endDate);
        }
        example.orderBy("date").asc();
        PageHelper.startPage(page, rows);
        List<WxSevenRetention> wxSevenRetentions = wxSevenRetentionMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(wxSevenRetentions)) {
            wxSevenRetentions.forEach(wxSevenRetention -> {
                WxSevenRetentionDTO wxSevenRetentionDTO = new WxSevenRetentionDTO();
                String date = wxSevenRetention.getDate();
                Example example1 = new Example(WxSubscribeStatistics.class);
                Example.Criteria criteria1 = example1.createCriteria();
                criteria1.andEqualTo("appId", appId);
                criteria1.andEqualTo("refDate", date);
                WxSubscribeStatistics subscribeStatistics = wxSubscribeStatisticsMapper.selectOneByExample(example1);
                wxSevenRetentionDTO.setDate(date);
                wxSevenRetentionDTO.setAppId(wxSevenRetention.getAppId());
                // 计算留存率
                if (Objects.nonNull(subscribeStatistics)) {
                    String newUserStr = subscribeStatistics.getNewUser();
                    wxSevenRetentionDTO.setNewUser(StringUtils.isNotBlank(newUserStr) ? newUserStr : ZERO_STR);
                    Integer newUser = 0;
                    if (StringUtils.isNotBlank(newUserStr)) {
                        newUser = Integer.valueOf(newUserStr);
                    }
                    wxSevenRetentionDTO.setZeroDay(getPercent(newUser, wxSevenRetention.getZeroDay(), 1));
                    wxSevenRetentionDTO.setOneDay(getPercent(newUser, wxSevenRetention.getOneDay(), 1));
                    wxSevenRetentionDTO.setTwoDay(getPercent(newUser, wxSevenRetention.getTwoDay(), 1));
                    wxSevenRetentionDTO.setThreeDay(getPercent(newUser, wxSevenRetention.getThreeDay(), 1));
                    wxSevenRetentionDTO.setFourDay(getPercent(newUser, wxSevenRetention.getFourDay(), 1));
                    wxSevenRetentionDTO.setFiveDay(getPercent(newUser, wxSevenRetention.getFiveDay(), 1));
                    wxSevenRetentionDTO.setSixDay(getPercent(newUser, wxSevenRetention.getSixDay(), 1));
                    wxSevenRetentionDTO.setSevenDay(getPercent(newUser, wxSevenRetention.getSevenDay(), 1));
                }
                dtos.add(wxSevenRetentionDTO);
            });
        }
        return new PageInfo<>(dtos);
    }

    /**
     * 查询列表-分页
     *
     * @param appId     公众号appId
     * @param beginDate 开始时间
     * @param endDate   结束时间
     * @param page
     * @param rows
     * @return
     */
    public PageInfo<WxSevenRetention> queryPageList(String appId, String beginDate, String endDate, Integer page, Integer rows) {
        Example example = new Example(WxSevenRetention.class);
        Example.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(appId)) {
            criteria.andEqualTo("appId", appId);
        }
        if (StringUtils.isNotBlank(beginDate)) {
            criteria.andGreaterThanOrEqualTo("date", beginDate);
        }
        if (StringUtils.isNotBlank(endDate)) {
            criteria.andLessThanOrEqualTo("date", endDate);
        }
        example.orderBy("date").asc();
        PageHelper.startPage(page, rows);
        List<WxSevenRetention> wxSevenRetentions = wxSevenRetentionMapper.selectByExample(example);
        return new PageInfo<>(wxSevenRetentions);
    }

    /**
     * 更新 -- 根据appId 和 date
     *
     * @param wxSevenRetention
     * @return
     */
    public int updateByAppIdAndDate(WxSevenRetention wxSevenRetention) {
        if (StringUtils.isBlank(wxSevenRetention.getAppId()) || StringUtils.isBlank(wxSevenRetention.getDate())) {
            LOGGER.warn("appId或者date为空，不进行更新操作！");
            return 0;
        }
        wxSevenRetention.setGmtModified(new Date());
        Example example = bulidExample(wxSevenRetention);
        return wxSevenRetentionMapper.updateByExampleSelective(wxSevenRetention, example);
    }

    /**
     * 组装条件
     *
     * @param wxSevenRetention
     * @return
     */
    Example bulidExample(WxSevenRetention wxSevenRetention) {
        if (Objects.nonNull(wxSevenRetention)) {
            Example example = new Example(WxSevenRetention.class);
            Example.Criteria criteria = example.createCriteria();
            String appId = wxSevenRetention.getAppId();
            String date = wxSevenRetention.getDate();
            if (StringUtils.isNotBlank(appId)) {
                criteria.andEqualTo("appId", appId);
            }
            if (StringUtils.isNotBlank(date)) {
                criteria.andEqualTo("date", date);
            }
            return example;
        }
        return null;
    }

}